home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-28 | 6.2 KB | 229 lines | [TEXT/MPS ] |
- /*
- File: DialogWindow.cp
-
- Contains: Implementation of a base class for Modeless Dialogs
-
- Written by: Dave Falkenburg
-
- Copyright: © 1993-94 by Dave Falkenburg, all rights reserved.
-
- Change History (most recent first):
-
- <7> 11/16/94 DRF Added explicit #include <Traps.h> for latest universal headers.
- <6> 11/12/94 DRF Fix a bug in EventFilter method which returned false even if a
- dialog item was hit.
- <5> 11/8/94 DRF We have better menu handling methods, so use them instead of the
- old “DoEditMenu” method.
- <3> 10/17/94 DRF ItemHit is now a pure-virtual method. Fixed bugs in DoEditMenu.
- Call StdFilterProc inside EventFilter to handle ok, cancel,
- and I-beam cursor tracking.
- <3> 9/27/94 DRF AppLib.h is now Sprocket.h
- <2> 9/9/94 DRF Reordered headers and removed redundant #includes. Also fixed
- constants in DoEditMenu.
- */
-
- #include "Sprocket.h"
- #include "DialogWindow.h"
- #include "StandardMenus.h"
- #include <Traps.h>
-
- TDialogWindow::TDialogWindow(DialogTemplateID dialogTemplateID)
- {
- fTemplateID = dialogTemplateID;
- this->CreateWindow(kNormalWindow);
- }
-
-
- WindowPtr
- TDialogWindow::MakeNewWindow(WindowPtr behindWindow)
- {
- return GetNewDialog(fTemplateID,nil,behindWindow);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////
- //
- // EventFilter strategy for Dialog Window
- //
- // Because of the need to patch and unpatch FrontWindow when calling IsDialogEvent
- // and DialogSelect, only do these things when a Modless Dialog is the frontmost
- // window. (e.g., it’s event filter is active)
- //
- // NOTE: We always pass events through, except when an item has been hit.
- //
- // You may be thinking that it is easier to just rewrite the Dialog Manager in
- // this program. You’re probably right.
-
- pascal WindowPtr FrontWindowPatchForDialogs();
-
-
- pascal WindowPtr
- FrontWindowPatchForDialogs()
- {
- return FrontNonFloatingWindow();
- }
-
- #define uppFrontWindowPatchProcInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
-
- UniversalProcPtr FrontWindowPatchUPP
- = (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) &FrontWindowPatchForDialogs,uppFrontWindowPatchProcInfo,GetCurrentISA());
-
-
- Boolean
- TDialogWindow::EventFilter(EventRecord *theEvent)
- {
- GrafPtr oldPort;
- UniversalProcPtr oldFrontWindow = GetToolboxTrapAddress(_FrontWindow);
- DialogPtr aDialog;
- Boolean eventHasBeenGobbled = false;
- short aDialogItem;
- short oldWindowKind;
-
- // Don’t snarf keypresses meant for menus
- if ((theEvent->what == keyDown) && (theEvent->modifiers & cmdKey))
- return false;
-
- GetPort(&oldPort);
- SetPort(fWindow);
-
- // Patch in our version of FrontWindow so that IsDialogEvent will do the right
- // thing. DialogManager should check both frontmost floating and frontmost
- // non-floating windows, however we don’t support floating dialogs.
- SetToolboxTrapAddress(FrontWindowPatchUPP,_FrontWindow);
-
- // Jam the windowKind of our dialog window back to dialogKind so that the
- // Dialog Manager can recognize our window as a dialog window.
- oldWindowKind = ((WindowPeek) fWindow)->windowKind;
- ((WindowPeek) fWindow)->windowKind = dialogKind;
-
-
- if (IsDialogEvent(theEvent))
- {
- // It’s definitely a dialog event, so let the DialogMgr figure things out.
- //
- // We first let StdFilterProc have a crack at it so that the default
- // and cancel buttons are properly processed (as well as automagic text
- // cursor tracking).
-
- // If StdFilterProc didn’t find anything to do, go ahead and call
- // DialogSelect to figure out if the user did anything important.
-
- // Isn’t this alot easier than what Inside Mac says to do?
-
- eventHasBeenGobbled = StdFilterProc(fWindow,theEvent,&aDialogItem);
- if (eventHasBeenGobbled == false)
- eventHasBeenGobbled = DialogSelect(theEvent,&aDialog,&aDialogItem);
- }
-
- // Restore the windowKind
- ((WindowPeek) fWindow)->windowKind = oldWindowKind;
-
- // Put FrontWindow back the way it really belongs
- SetToolboxTrapAddress((UniversalProcPtr) oldFrontWindow,_FrontWindow);
-
- if (eventHasBeenGobbled)
- {
- this->ItemHit(aDialogItem); // Call user’s method to deal with a hit
- eventHasBeenGobbled = true;
- }
-
- SetPort(oldPort);
-
- return eventHasBeenGobbled;
- }
-
-
- void
- TDialogWindow::Activate(Boolean activating)
- {
- EventRecord fakeEvent;
-
- /* (De)activates are NOT automagically handled because our floating
- * windows prevent real activate events from ever being generated
- * for any non-floaters windows.
- *
- * Our strategy is to fool the dialog manager into thinking that
- * things are still fine by passing it a fake (de)activate event.
- *
- * Luckily, we don’t have to patch FrontWindow to make DialogSelect
- * work for activate and update events.
- */
-
- OSEventAvail(0,&fakeEvent); // Get an intialized, but otherwise empty event record
-
- fakeEvent.what = activateEvt;
- fakeEvent.message = (unsigned long) fWindow;
- if (activating)
- fakeEvent.modifiers |= activeFlag;
- else
- fakeEvent.modifiers &= ~activeFlag;
-
- // Pass event on to DialogSelect
-
- DialogPtr aDialog;
- short aDialogItem;
-
- (void) DialogSelect(&fakeEvent,&aDialog,&aDialogItem);
- }
-
-
- void
- TDialogWindow::Draw(void)
- {
- // Automagically handled by Dialog Manager when we are
- // the frontmost window, but not at other times because
- // we only set the windowKind to dialogKind inside our
- // EventFilter (which is only active when we are frontmost).
-
- UpdateDialog((DialogPtr) fWindow, fWindow->visRgn);
- }
-
-
- void
- TDialogWindow::Click(EventRecord * /* anEvent */)
- {
- /* The only time this method is called is to handle a click
- * when the dialog window isn’t frontmost. All other times,
- * DialogSelect will do everything for us.
- *
- * If our dialog contains useritems with the ability to
- * be the source of a drag we’d need to start drag tracking
- * in here.
- */
-
- this->Select();
- }
-
-
- void
- TDialogWindow::DoMenuSelection(short menu, short item)
- {
- if (menu == mEdit)
- {
- switch (item)
- {
- case iUndo:
- break;
-
- case iCut:
- DialogCut(fWindow);
- return;
-
- case iCopy:
- DialogCopy(fWindow);
- return;
-
- case iPaste:
- DialogPaste(fWindow);
- return;
-
- case iClear:
- DialogDelete(fWindow);
- return;
- }
- }
-
- // Call through to inherited method
- TWindow::DoMenuSelection(menu,item);
- }
-